using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using Sedna.Core.Controller;
using Sedna.Core.Controller.Configurations;
using Sedna.Core.Controls.Support;
using Sedna.Core.Controls.Support.Javascript;
using Sedna.Core.DataBinding;
using Sedna.Core.Tiles.Contents;
using Sedna.Util;
using DataBinder=Sedna.Core.DataBinding.DataBinder;

namespace Sedna.Core.Controls
{
	public class CheckBox : System.Web.UI.WebControls.CheckBox, IContent, IConfigurationAware,  
		ILabelledControl, IClientScriptingControl, IControlDataLoadAware
    {
        #region Fields

        private ICheckBoxConfiguration configuration;
		private string configurationId = "configuration.default.CheckBox";
		private string textKey;

        private bool originalVisible;

		private string clientVariable;
		private bool clientScriptingEnabled;
        private string javascriptClass;

		private String contentPlaceHolderId;

		protected IDataBinder binder;

        private string toolTipKey;

        #endregion

        #region Properties

        public String ContentPlaceHolderId
		{
			get { return contentPlaceHolderId;}
			set { contentPlaceHolderId = value;}
		}

		IConfiguration IConfigurationAware.Configuration
		{
			get { return configuration; }
			set { this.configuration = (ICheckBoxConfiguration) value; }
		}

		public ICheckBoxConfiguration Configuration
		{
			get { return configuration; }
			set { this.configuration = value; }
		}


		public string TextKey
		{
			get
			{
				return textKey;
			}
			set
			{
				textKey = value;
			}
		}

        public virtual string ToolTipKey
        {
            get { return toolTipKey; }
            set { toolTipKey = value; }
        }

        public string LocalizedToolTip
        {
            get
            {
                if (Configuration.DataTranslator != null && Configuration.DataTranslator.GetType() != typeof(TrivialDataTranslator))
                {
                    return ToolTip;
                }
                return Configuration.GetLocalizedPostfixLabel(ToolTipKey, ToolTip);
            }
        }
  
		[Bindable(true), Category("Sedna"), DefaultValue("configuration.default.CheckBox")]
		public string ConfigurationId
		{
			get { return configurationId; }
			set { this.configurationId = value; }
		}

		public string ClientVariable
		{
            get { return ControlUtil.GetClientVariable(this, clientVariable); }
			set { clientVariable = value; }
		}

		public bool ClientScriptingEnabled
		{
			get { return /*clientVariable!=null||*/clientScriptingEnabled; }
			set { clientScriptingEnabled = value; }
		}

      #endregion


        #region Javascript support
	    
        public string JavascriptClass
	    {
	        get { return javascriptClass; }
	        set { javascriptClass = value; }
        }

	    public string NodeName
	    {
            get { return ClientID + "_outer"; }
        }

        private void RenderScriptAttributes(HtmlTextWriter writer)
        {
            if (!ClientScriptingEnabled)
            {
                return;
            }
            writer.AddAttribute("ID", NodeName);
            foreach (DictionaryEntry entry in BuildScriptParameters())
            {
                writer.AddAttribute("sedna:" + (string)entry.Key, (string)entry.Value);
            }
        }

        private void DeclareScriptVariable()
        {
            if (!ClientScriptingEnabled)
            {
                return;
            }
            ControlUtil.EnsureIdAttribute(this);
            JavascriptController.Current.DeclareClass(JavascriptClass);
            if (ClientVariable != null)
            {
                JavascriptController.Current.DeclareObjectByNode(ClientVariable, JavascriptClass, NodeName);
            }
        }

        protected virtual IDictionary BuildScriptParameters()
        {
            IDictionary parameters = new ListDictionary();
            parameters.Add("clientId", ClientID);
            parameters.Add("text", Text);
            parameters.Add("checked", new ScriptObjectGenerator(Checked).ToScript());
            parameters.Add("jsClass", JavascriptClass);
            return parameters;
        }
	    
        #endregion

        #region Constructors
        public CheckBox()
			:base()
		{
			this.CssClass = "checkbox";
		}

		public CheckBox(IConfiguration configuration): this()
		{
			this.configuration = (ICheckBoxConfiguration) configuration;
			this.configurationId = configuration.ObjectName;
//			this.ID = configuration.Id;
			BuildControlFromConfiguration();
        }

        #endregion

	    protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
	    {
            Control control = this;
	        while (control!=null)
	        {
                if (control.Visible == false) return false;
                control = control.Parent;
	        }
	        return base.LoadPostData(postDataKey, postCollection);
	    }

	    protected override void OnInit(EventArgs e)
		{
			if (configuration == null)
			{
				configuration = (ICheckBoxConfiguration)SpringContextFactory.GetContext().GetObject(configurationId);
                Build();
			}
			ControlUtil.SetupClientAttributes(this, configuration);
//			ControlUtil.SetupValidators(this, configuration);            
			binder=new DataBinder(this, configuration, ExecutionContext.GetCurrent(ClientID));
			base.OnInit (e);
		}

		protected void Build()
		{
			this.Visible = configuration.IsVisibleForPrincipal() && configuration.Visible;
			this.Enabled = configuration.IsEnabledForPrincipal() && configuration.Enabled;

//			BuildControlFromConfiguration();
		}

		protected void BuildControlFromConfiguration()
		{
			this.ID = configuration.Id;
			this.TextKey = configuration.TextKey;
			if (configuration.CssClass!=null)
			{
				this.CssClass = configuration.CssClass;
			}
				
			ClientScriptingEnabled = configuration.ClientScriptingEnabled;
			ClientVariable = configuration.ClientVariable;
            JavascriptClass = configuration.JavascriptClass;
			Checked=configuration.Checked;
		    Enabled = configuration.Enabled;            

            Build();
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
		    
			IDictionary executionContext = ExecutionContext.GetCurrent(ClientID);
		    
            Text = configuration.GetLocalizedPostfixLabel(TextKey, Text);
		    
			Unbind();
			
		    ControlUtil.ExecuteOnLoad(executionContext, Context, Configuration, this.ClientID);

            # region Visibility

            originalVisible = Visible;

            if (Configuration.VisibleBindPath != null)
                Visible = true; // To reach the OnPreRender method and analyze visibility in the Bind method

            # endregion

		}

	    protected override void AddAttributesToRender(HtmlTextWriter writer)
	    {
	        base.AddAttributesToRender(writer);
            RenderScriptAttributes(writer);
	    }

	    protected override void OnPreRender(EventArgs e)
		{
			IDictionary executionContext = ExecutionContext.GetCurrent(ClientID);
			ControlUtil.ExecuteOnPreRender(executionContext,Context, Configuration, this.ClientID);
			Bind();
            Text = Configuration.GetLocalizedPostfixLabel(TextKey, Text);
            this.ToolTip = LocalizedToolTip;
            DeclareScriptVariable();
	        base.OnPreRender(e);			
		}

		public void OnDataLoad()
		{
			IDictionary executionContext = ExecutionContext.GetCurrent(ClientID);
			ControlUtil.ExecuteOnDataLoad(executionContext, Context, Configuration, this.ClientID);
		}

		protected virtual void Bind()
		{
            if (!Configuration.DoBind)
            {
                Visible = originalVisible;
                return;
            }
		    
            Visible = configuration.Visible;

            binder.Bind(new string[] { "Checked", "Text", "TextKey", "Enabled", "Visible" });

            Enabled = Enabled && configuration.IsEnabledForPrincipal();
            Visible = Visible && configuration.IsVisibleForPrincipal();

            ToolTip = Configuration.ToolTip;
            ToolTipKey = Configuration.ToolTipKey;
            binder.Bind("ToolTip");
            binder.Bind("ToolTipKey");

		}

		protected virtual void Unbind()
		{
            if (!Configuration.DoUnbind)
                return;
		    			
            binder.Unbind(new string[] { "Checked", "Text", "TextKey", "Enabled", "Visible" });

            binder.Unbind("ToolTip");
            binder.Unbind("ToolTipKey");
		}


	}
}
